/**
 *
 * © Bahadir Zeren 2011
 * bzeren@gmail.com
 * No warranties, express or implied, are made for this program.
 *
 */
package org.baatar.opt.genetic.set.meta;

import java.io.FileWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 
 * 
 * @author B_ZEREN
 */
public class DataSet implements Serializable {
    public Row rows[] = null;
    public Column columns[] = null;

    private int rowCounter = 0;
    private int columnCounter = 0;

    public void setRowsArray(int numOfRows) {
        this.rows = new Row[numOfRows];
    }

    public void setColsArray(int numOfColumns) {
        this.columns = new Column[numOfColumns];
    }

    public void addRow(int cost, String info) {
        Row row = new Row();
        row.cost = cost;
        row.info = info;
        row.ndx = rowCounter;
        rows[rowCounter] = row;
        rowCounter++;
    }

    public void addColumn(int cost, int layoverCost, double quality, String rowStr) {
        Column column = new Column();
        column.cost = cost;
        column.layoverCost = layoverCost;
        column.quality = quality;
        int i = 0;
        int j = 0;
        ArrayList<Row> rowList = new ArrayList<Row>();
        while (true) {
            j = rowStr.indexOf(',', i);
            if (j < 0)
                break;
            String rowNdxStr = rowStr.substring(i, j);
            int rowNdx = Integer.valueOf(rowNdxStr);

            Row row = rows[rowNdx];
            rowList.add(row);

            /**
             *   Causes java.lang.StackOverflowError problem during streaming of the object via serialization
             */
//            if (row.columns == null)
//                row.columns = new ArrayList<Column>();
//            row.columns.add(column);

            i = j + 1;
        }

        column.rows = new Row[rowList.size()];
        for (int r = 0; r < rowList.size(); r++) {
            column.rows[r] = rowList.get(r);
        }

        column.ndx = columnCounter;
        columns[columnCounter] = column;
        columnCounter++;
    }

    public void init() {
        for (int i = 0; i < columns.length; i++) {
            Column column = columns[i];
            for (int j = 0; j < column.rows.length; j++) {
                Row row = columns[i].rows[j];
                if (row.columns == null)
                    row.columns = new Column[1];
                else
                    row.columns = Arrays.copyOf(row.columns, row.columns.length + 1);
                row.columns[row.columns.length - 1] = column;
            }
        }
    }

    public void writeMatlabCode() {
        try {
            FileWriter fw = new FileWriter("F:\\scp.m");
            try {
                fw.append("clear\n\n")
                    .append("f=[")
                    .append(String.valueOf(columns[0].cost));
                for (int i = 1; i < columns.length; i++) {
                    fw.append("\t")
                        .append(String.valueOf(columns[i].cost))
                        .append(".0");
                }
                fw.append("];")
                    .append("\n\n");

                fw.append("A=[");
                for (int r = 0; r < rows.length; r++) {
                    Row row = rows[r];
                    if (row.columns != null) {
                        for (int c = 0; c < columns.length; c++) {
                            Column col = columns[c];

                            boolean covers = false;
                            for (int rc = 0; rc < row.columns.length; rc++) {
                                if (col == row.columns[rc]) {
                                    covers = true;
                                    break;
                                }
                            }
                            if (covers)
                                fw.append("\t1");
                            else
                                fw.append("\t0");
                        }
                        fw.append(";\n");
                    }
                }
                fw.append("];\n\n");

                fw.append("b=[");
                for (int r = 0; r < rows.length; r++) {
                    if (rows[r].columns != null)
                        fw.append("1;\t");
                }
                fw.append("];\n\n");
                fw.append("[t fval exitflag output]=bintprog(f,-A,-b)\n\n");
            } finally {
                fw.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public double calculateSolutionCost(int solNdx[]) {

        double res = 0.0;

        for (int i = 0; i < solNdx.length; i++) {
System.out.println(solNdx[i] + " - " + columns[solNdx[i]].cost);
            res += columns[solNdx[i]].cost;
        }

        return res;
    }
}
